/**
 * 
 */
package _runnable_classes;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.TimeZone;

import primary_classes.SystemVars;
import secondary_classes.Order;
import secondary_classes.OrdersComparatorBidIdAskId;
import secondary_classes.ReadOrders;
import secondary_classes.SortedList;
import secondary_classes.StopWatch;

/**
 * @author Rohit
 *
 */
public class TradesComparator {

	// CONSTANTS
	private static       String     SYSTEM_VARS_IN  = "SystemVars.txt";
	private static final String     SYSTEM_VARS_OUT = "status.txt";
	private static final DateFormat timeFormat      = new SimpleDateFormat("HH:mm:ss.SSS");
	
	// ATTRIBUTES
	private static SystemVars systemVars;
	public  static ReadOrders ordersData1;
	public  static ReadOrders ordersData2;
	private static StopWatch  s = new StopWatch();
	private static String     inputFilePath1;
	private static String     inputFilePath2;
	
	private static int        allTrades;
	private static int        nearMatches;
	private static int        exactMatches;

	private static boolean console = false;
	/**
	 * Do not call this method.  Used in the console version of the application
	 */
	public static void main(String[] args) {
		console = true;
		if (args.length == 1) {
			SYSTEM_VARS_IN = args[0];
		}
		
		new TradesComparator("", "", "");
		
	}
	
	/**
	 * Creates a new TradesComparator
	 * @param inputFile the name of the input file (including file extension)
	 * @param inputDir location of the input file
	 * @param outputFileDir location of the output directory
	 */
	public TradesComparator(String inputFile, String inputDir, String outputFileDir) {
		nearMatches = 0;
		exactMatches = 0;
		
		//String error = "";
	    
	    timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
	    s.start();
	    
	    //code you want to time goes here

		try {

			System.out.print(elapsedTimeString() + "  READING SYSTEM VARIABLES" + "\r");
			if (console) {
				systemVars = new SystemVars(SYSTEM_VARS_IN, SYSTEM_VARS_OUT);
			} else {
				systemVars = new SystemVars(inputFile, inputDir, SYSTEM_VARS_OUT, outputFileDir, 0);
			}
			System.out.println(elapsedTimeString() + "  READING SYSTEM VARIABLES - Done");
			
			readInput();
			getMatches(ordersData1, ordersData2);
			System.out.println("Exact matches = " + exactMatches);
			System.out.println("Near matches = " + nearMatches);
			System.out.println("Number of trades = " + allTrades);
			writeTradesCompFile();
			s.stop();
		} catch (Exception e) {
			s.stop();
			e.printStackTrace();
		}
	}
	
	private static void writeTradesCompFile() throws Exception {
		BufferedWriter b;
		try {
			b = new BufferedWriter(new FileWriter(SystemVars.getTradesComparatorFile()));
		} catch (Exception e) {
			throw new Exception("Could not write trades comparator file.");
		}
		
		String result = "";
		
		result += "Time elapsed  = " + timeFormat.format(s.getElapsedTime()) + "\n";
		result += "\n";
		result += "Exact matches = " + exactMatches + "\n";
		result += "Near matches  = " + nearMatches + "\n";
		result += "Total trades  = " + allTrades + "\n";
		result += "\n";
		result += "Exact match percentage = " + (((float) exactMatches / (float) allTrades) * 100) + "%\n";
		result += "Near match percentage  = " + (((float) nearMatches  / (float) allTrades) * 100) + "%\n";
		
		b.write(result);
		b.close();
	}

	private static void readInput() throws Exception {
		// read in the input file supplied by the SystemVars
		if (systemVars == null) {
			throw new Exception("System variables not entered correctly");
		}
		
		inputFilePath1 = SystemVars.getInputFile().getAbsolutePath();
		inputFilePath2 = SystemVars.getTradesFile().getAbsolutePath();
		
		System.out.print(TradingEngine.elapsedTimeString() + "  READING INPUT" + "\r");
		try {
			ordersData1 = new ReadOrders(inputFilePath1, true);
		} catch (Exception e) {
			throw new Exception("Reading real orders file - " + e.getMessage());
		}
		
		try {
			ordersData2 = new ReadOrders(inputFilePath2, true);
		} catch (Exception e) {
			throw new Exception("Reading generated trades file - " + e.getMessage());
		}
		
	}
	
	private static void getMatches(ReadOrders readOrders1, ReadOrders readOrders2) {
		Comparator<Order> comp = new OrdersComparatorBidIdAskId();
		SortedList orders1 = new SortedList(comp);
		SortedList orders2 = new SortedList(comp);
		
		orders1.addAll(readOrders2.getOrders());
		orders2.addAll(readOrders1.getOrders());
		
		allTrades = orders1.size();
		
		for (int i = 0; i < orders1.size(); i++) {
			// find matching trade
			int j = Collections.binarySearch(orders2, orders1.get(i), comp);
			// check to see what type of match
			if (j >= 0) { // if there is a match
				if (orders1.get(i).exactMatch(orders2.get(j))) {
					exactMatches++;
				} else {
					nearMatches++;
				}
			}
		}
	}

	public static String elapsedTimeString() {
		Date d = new Date(s.getElapsedTime());
		return "Elapsed Time = " + timeFormat.format(d);
	}

}
